using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace CR.Infrastructure
{
    public interface IBaseRepository<TEntity> where TEntity : class
    {
        /// <summary>
        /// 根据ID获取实体
        /// </summary>
        /// <param name="id">实体ID</param>
        /// <returns>实体对象</returns>
        Task<TEntity> GetByIdAsync(object id);

        /// <summary>
        /// 获取所有实体
        /// </summary>
        /// <returns>实体列表</returns>
        Task<IEnumerable<TEntity>> GetAllAsync();

        /// <summary>
        /// 根据条件查询实体
        /// </summary>
        /// <param name="predicate">查询条件表达式</param>
        /// <returns>符合条件的实体列表</returns>
        Task<IEnumerable<TEntity>> FindAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 根据条件查询单个实体
        /// </summary>
        /// <param name="predicate">查询条件表达式</param>
        /// <returns>符合条件的单个实体</returns>
        Task<TEntity> SingleOrDefaultAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 添加实体
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns>添加后的实体</returns>
        Task<TEntity> AddAsync(TEntity entity);

        /// <summary>
        /// 批量添加实体
        /// </summary>
        /// <param name="entities">实体列表</param>
        /// <returns>添加后的实体列表</returns>
        Task<IEnumerable<TEntity>> AddRangeAsync(IEnumerable<TEntity> entities);

        /// <summary>
        /// 更新实体
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns>更新后的实体</returns>
        Task<TEntity> UpdateAsync(TEntity entity);

        /// <summary>
        /// 批量更新实体
        /// </summary>
        /// <param name="entities">实体列表</param>
        /// <returns>更新后的实体列表</returns>
        Task<IEnumerable<TEntity>> UpdateRangeAsync(IEnumerable<TEntity> entities);

        /// <summary>
        /// 删除实体
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns>操作结果</returns>
        Task<bool> RemoveAsync(TEntity entity);

        /// <summary>
        /// 批量删除实体
        /// </summary>
        /// <param name="entities">实体列表</param>
        /// <returns>操作结果</returns>
        Task<bool> RemoveRangeAsync(IEnumerable<TEntity> entities);

        /// <summary>
        /// 根据ID删除实体
        /// </summary>
        /// <param name="id">实体ID</param>
        /// <returns>操作结果</returns>
        Task<bool> RemoveByIdAsync(object id);

        /// <summary>
        /// 判断是否存在满足条件的实体
        /// </summary>
        /// <param name="predicate">查询条件表达式</param>
        /// <returns>是否存在</returns>
        Task<bool> ExistsAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 获取满足条件的实体数量
        /// </summary>
        /// <param name="predicate">查询条件表达式</param>
        /// <returns>实体数量</returns>
        Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate = null);

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">每页大小</param>
        /// <param name="predicate">查询条件表达式</param>
        /// <param name="orderBy">排序表达式</param>
        /// <param name="isAsc">是否升序</param>
        /// <returns>分页结果</returns>
        Task<(IEnumerable<TEntity> Data, int Total)> GetPagedListAsync(
            int pageIndex, 
            int pageSize, 
            Expression<Func<TEntity, bool>> predicate = null, 
            Expression<Func<TEntity, object>> orderBy = null, 
            bool isAsc = true);
    }
} 